문제 14369
전화번호 수수께끼(Small)
입력 : 첫 줄에 테스트케이스의 개수 T가 주어진다. 각 테스트케이스에는 상대방이 제시한 스트링 S가 주어진다. S는 영어 대문자로만 이루어져 있다.
1≤ T ≤ 100이고, S의 길이는 3 이상 20 이하이다. 모든 테스트케이스에는 유일한 해답이 있다.
출력 : 각 줄에 테스트케이스 번호 x와 전화번호 y를 Case # x: y의 형태로 출력한다.
첫 시도 -> 시간초과
ZERO = [1,0,0,0,0,0,1,1,0,0,0,0,0,0,1]
ONE = [1,0,0,0,0,1,1,0,0,0,0,0,0,0,0]
TWO = [0,0,0,0,0,0,1,0,0,1,0,0,1,0,0]
THREE =[2,0,0,1,0,0,0,1,0,1,0,0,0,0,0]
FOUR = [0,1,0,0,0,0,1,1,0,0,1,0,0,0,0]
FIVE = [1,1,0,0,1,0,0,0,0,0,0,1,0,0,0]
SIX = [0,0,0,0,1,0,0,0,1,0,0,0,0,1,0]
SEVEN =[2,0,0,0,0,1,0,0,1,0,0,1,0,0,0]
EIGHT =[1,0,1,1,1,0,0,0,0,1,0,0,0,0,0]
NINE = [1,0,0,0,1,2,0,0,0,0,0,0,0,0,0]
NUMBER = [ ["0",ZERO], ["1", ONE], ["2", TWO], ["3", THREE], ["4", FOUR], ["5", FIVE], ["6", SIX], ["7", SEVEN], ["8", EIGHT], ["9",NINE] ]
ALPHABET = ['E', 'F', 'G', 'H', 'I', 'N', 'O', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Z']
def CASE(TEXT, ALPHABET = ALPHABET):
result = []
for i in ALPHABET:
result.append(TEXT.count(i))
return result
def CLEAR_NUMBER(NUMBER = NUMBER, case = []):
number = []
#전처리
for i in NUMBER:
detect = 0
for j in range(15):
if i[1][j] > case[j]:
detect = 1
break
if detect == 0:
number.append(i)
case = [y-x for x,y in zip(i[1], case)]
return number, case
def ANSWER(case, number = NUMBER):
answer = []
case = CASE(case)
while True:
if case == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]:
break
number, case = CLEAR_NUMBER(number, case)
for i in number:
answer.append(i[0])
return answer
answer = []
for i in range(int(input())):
case = input()
a = ""
for j in sorted(ANSWER(case)):
a += j
answer.append(a)
m = 1
for i in answer:
print("Case "+"#"+str(m)+": "+i)
m += 1
'E', 'F', 'G', 'H', 'I', 'N', 'O', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Z'
를 차례대로 묶어서, 해당 알파벳이 있으면 1
, 없으면 0
을 매겨주었다. 그리고 주어진 case
에서, 해당되는 알파벳 부분을 전체에서 빼주는 작업을
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
이 될 때까지 반복해서
정답을 찾는 방법으로 작성했다.
CLEAR_NUMBER
함수는 NUMBER
리스트를 순회하면서 각 숫자의 패턴과 case
를 비교하는데, 매 숫자마다 15개의 값을 비교하고, 이를 매번 갱신하며 반복적으로 수행하는 점이 시간을 많이 잡아먹었고.. case
가 0으로 수렴하는 과정에서 반복 횟수가 많아지고, 내부적으로 CLEAR_NUMBER
를 여러 번 호출하므로 시간이 크게 소요되어서 시간초과가 났을 것이다.네 번째 시도
from collections import Counter
DIGITS = [
["0", "Z", "ZERO"],
["2", "W", "TWO"],
["4", "U", "FOUR"],
["6", "X", "SIX"],
["8", "G", "EIGHT"],
["3", "H", "THREE"],
["5", "F", "FIVE"],
["7", "V", "SEVEN"],
["1", "O", "ONE"],
["9", "I", "NINE"],
]
def solve_case(case):
case_count = Counter(case)
result = []
for digit, unique_char, word in DIGITS:
count = case_count[unique_char]
if count > 0:
result.extend([digit] * count)
for char in word:
case_count[char] -= count
return "".join(sorted(result))
# 입력 처리
t = int(input())
answers = []
for i in range(t):
case = input().strip()
answers.append(f"Case #{i + 1}: {solve_case(case)}")
print("\n".join(answers))
그냥 아예 각 알파벳이 고유하게 가지고 있는 문자열을 비교해서 빼주는 방식으로 진행했다.
["1", "O", "ONE"]
같은 경우 "O"가 "ZERO"에도 있고 "TWO"에도 있고 "FOUR" 에도 있기 때문에 문제가 될 거 같지만 애당초 "ZERO"는 유일한 "Z"에 의해 다 걸러지게 되고, 마찬가지로 "TWO"는 "W"에, "FOUR"는 "U"에 걸러지게 되므로 상관 없다.from collections import Counter
를 사용해서 시간을 줄였다.